using AnimCollections;
using System;
using System.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;

namespace DA.AnimGraph {

    public class AGEPreviewConnection : IDisposable {

        public class GraphData {
            public Blackboard bb;
            public Dictionary<string, AGABlackboardType> bbInfo;
        }

        private AGEPreviewPlayer player;
        private DynamicBlackboard dynamicBlackboard;

        private Dictionary<string, GraphData> graphsData;

        public AGEPreviewConnection(AGEPreviewPlayer previewPlayer) {
            graphsData = new();
            player = previewPlayer;
            player.Holding();
        }

        public void Dispose() {
            foreach (var data in graphsData) {
                data.Value.bb.Dispose();
            }
            player.StopPreview();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name">做字典key</param>
        /// <param name="agp"></param>
        /// <param name="resources"></param>
        /// <param name="bbInfo"></param>
        /// <param name="slotName"></param>
        /// <returns>是否添加成功</returns>
        public bool AddGraph(string name, AnimGraphPublishAsset agp, Dictionary<AUID, Object> resources, Dictionary<string, AGABlackboardType> bbInfo, string slotName) {
            Debug.Assert(agp != null);
            if (!dynamicBlackboard.isValid) {
                dynamicBlackboard = new DynamicBlackboard(bbInfo.Count);
            }
            var bb = new Blackboard(bbInfo.Count);
            var bbAddr = new Dictionary<string, ulong>(bbInfo.Count);
            bb.SetBaseAddress(dynamicBlackboard.baseAddr);
            foreach (var info in bbInfo) {
                // if (dynamicBlackboard.isFull) {
                //     Debug.Log("DynamicBlackboard 已满，检查能否正常扩容");
                //     // throw new Exception("DynamicBlackboard 过量分配变量，检查空间为什么不够");
                // }
                var addr = dynamicBlackboard.Allocate();
                bb.BindFieldByAddress(info.Key, addr);
                bbAddr[info.Key] = addr;
            }
            player.StartPreview2(agp, resources, dynamicBlackboard, bb, slotName, name);
            graphsData[name] = new GraphData() {
                bb = bb,
                bbInfo = bbInfo,
            };
            return true;
        }

        public unsafe AGTree GetAGTree() {
            if (player == null) {
                return null;
            }
            var controller = player.GetAnimGraphController();
            var agTree = controller->GetAGTree();
            if (agTree == null) {
                agTree = new();
            }
            return agTree;
        }

    }
}
